#include "../EventLoop.h"
#include "../EventLoopThread.h"
#include "../EventLoopThreadPool.h"
#include <cassert>
using namespace yhaida;

EventLoopThreadPool::EventLoopThreadPool(EventLoop *baseLoop)
    : _baseLoop(baseLoop),
      _started(false),
      _numThreads(0),
      _next(0)
{
}
EventLoopThreadPool::~EventLoopThreadPool()
{
}

// void EventLoopThreadPool::start()
// {
//     assert(!_started);
//     _baseLoop->assertInLoopThread();
//     _started = true;
//     for (int i = 0; i < _numThreads; ++i)
//     {
//         std::unique_ptr<EventLoopThread> loop(new EventLoopThread());
//         _threads.push_back(std::move(loop));
//         // _loops.push_back(loop->startLoop());
//         _loops.push_back(_threads.back()->startLoop());
//     }
// }
void EventLoopThreadPool::start(const ThreadInitCallback &cb)
{
    assert(!_started);
    _baseLoop->assertInLoopThread();
    _started = true;
    for (int i = 0; i < _numThreads; ++i)
    {
        std::unique_ptr<EventLoopThread> loop(new EventLoopThread(cb));
        _threads.push_back(std::move(loop));
        // _loops.push_back(loop->startLoop());
        _loops.push_back(_threads.back()->startLoop());
    }
    if (_numThreads == 0 && cb)
    {
        cb(_baseLoop);
    }
}

EventLoop *EventLoopThreadPool::getNextLoop()
{
    _baseLoop->assertInLoopThread();
    EventLoop *loop = _baseLoop;
    if (!_loops.empty())
    {
        loop = _loops[_next];
        ++_next;
        if (static_cast<size_t>(_next) >= _loops.size())
        {
            _next = 0;
        }
    }
    return loop;
}
